#pragma once

//#define load_on_GJZ vector<vector<token>> vtt;\
//				vector<token> vt;\
//				if(a<vstr.size()-1&&vstr[a+1].str=="("){\
//					int a=0,k=a+2;\
//					for(;vstr[k].str!=")"||a;k++){\
//						if(k>vstr.size()-1){\
//							throw(error("SyntaxError : Except a \')\' in the end of the line but not found."));\
//						}\
//						if(vstr[k].str=="(")a++;\
//						else if(vstr[k].str==")")a--;\
//						if(vstr[k].str==","&&!a){\
//							vtt.push_back(vt);\
//							vt.clear();\
//						}else{\
//							vt.push_back(vstr[k]);\
//						}\
//					}\
//					vtt.push_back(vt);\
//					vstr.erase(vstr.begin()+a,vstr.begin()+k+1);\
//				}else{\
//					throw(error("SyntaxError : Except a \'(\' after print but not found."));\
//				}

struct error{
	string mess;
	error(const string&str):mess(str){}
};

value atov(const string &str){
	if(str[0]=='\"'){
		value v;
		v.ty=Z_STR;
		string a=str;
		a=a.c_str()+1;
		a.erase(a.size()-1,a.size()-1);
		v.data.strp=new string(a);
		pool.insert(v.data.strp);
		return v;
	}
	if((str[0]>='0'&&str[0]<='9')||str[0]=='+'||str[0]=='-'){
		value v;
		v.ty=Z_INT;
		v.data.ll=atoll(str.c_str());
		return v;
	}
	cout<<str;
	return value();
}

vector<token> explain(vector<token> vstr,int pc){
	/* zhushi chuli */
	for(int a=0;a<vstr.size();a++){
		if(vstr[a].str=="//"){
			vstr.erase(vstr.begin()+a, vstr.end());
			break;
		}
	}
	/* GJZ 关键字 */
	for(int a=0;a<vstr.size();a++){
		if(vstr[a].str==""){
			continue;
		}
		if(vstr[a].wv==Z_GJZ){
			if(vstr[a].str=="print"){
				vector<vector<token>> vtt;int pk=0;vector<token> vt;
				if(a+1>=vstr.size()){
					throw error("SyntaxError : Expect a \'(\' after print but not found");
				}
				if(vstr[a+1].str=="("){
					vstr[a].str="";
					vstr[a+1].str="";
					a+=2;
					for(;pk||vstr[a].str!=")";a++){
						if(a>=vstr.size()){
							throw error("SyntaxError : Expect a ')' in the end of the line");
						}
						//cout<<vstr[a].str<<"|";
						if(vstr[a].str=="("){
							pk++;
						}else if(vstr[a].str==")"){
							pk--;
						}
						if(pk){
							vt.push_back(vstr[a]);
						}else{
							if(vstr[a].str==","){
								vtt.push_back(vt);
								vt.clear();
							}else{
								vt.push_back(vstr[a]);
							}
						}
						vstr[a].str="";
						//cout<<"|"<<vstr[a].str<<"|";
					}
					vstr[a].str="";
					vtt.push_back(vt);
				}else{
					throw(error("SyntaxError : Expect a \'(\' after print but not found"));
				}
				for(vector<token> &onarg:vtt){
					for(token &onet:explain(onarg,pc)){
						//cout<<"{"<<onet.str<<"}";
						if(onet.str=="")continue;
						value va=atov(onet.str);
						switch(va.ty){
							case Z_REAL:
								cout<<va.data.ld;
								break;
							case Z_INT:
								cout<<va.data.ll;
								break;
							case Z_STR:
								cout<<*va.data.strp;
								break;
							default:
								//cout<<int(va.ty);
								throw error("RuntimeError : Can\'t output the value that\'s type is a unknown type");
								break;
						}
					}
				}
			}else if(vstr[a].str=="in"){
				vector<vector<token>> vtt;int pk=0;vector<token> vt;int olda=a;
				if(a+1>=vstr.size()){
					throw error("SyntaxError : Expect a \'(\' after print but not found");
				}
				if(vstr[a+1].str=="("){
					vstr[a].str="";
					vstr[a+1].str="";
					a+=2;
					for(;pk||vstr[a].str!=")";a++){
						if(a>=vstr.size()){
							throw error("SyntaxError : Expect a ')' in the end of the line");
						}
						//cout<<vstr[a].str<<"|";
						if(vstr[a].str=="("){
							pk++;
						}else if(vstr[a].str==")"){
							pk--;
						}
						if(pk){
							vt.push_back(vstr[a]);
						}else{
							if(vstr[a].str==","){
								vtt.push_back(vt);
								vt.clear();
							}else{
								vt.push_back(vstr[a]);
							}
						}
						vstr[a].str="";
						//cout<<vstr[a].str;
					}
					vstr[a].str="";
					vtt.push_back(vt);
				}else{
					throw(error("SyntaxError : Expect a \'(\' after print but not found"));
				}
				for(vector<token> &onarg:vtt){
					for(token &onet:explain(onarg,pc)){
						//cout<<"{"<<onet.str<<"}";
						value va=atov(onet.str);
						switch(va.ty){
							case Z_REAL:
							case Z_STR:
							case Z_INT:{
								if(olda==-1){
									throw error("Syntax error: Only one arg is expected at most in the in parameter section.");
								}
								string str;
								cin>>str;
								vstr[olda].str=str;
								vstr[olda].wv=Z_ATOMIC;
								olda=-1;
								break;
							}
							default:
								//cout<<va.ty; 
								throw error("RuntimeError : Can\'t input the value that\'s type is a unknown type");
								break;
						}
					}
				}
			}else if(vstr[a].str=="exit"){
				vector<vector<token>> vtt;int pk=0;vector<token> vt;
				if(a+1>=vstr.size()){
					throw error("SyntaxError : Expect a \'(\' after print but not found");
				}
				if(vstr[a+1].str=="("){
					vstr[a].str="";
					vstr[a+1].str="";
					a+=2;
					for(;pk||vstr[a].str!=")";a++){
						if(a>=vstr.size()){
							throw error("SyntaxError : Expect a ')' in the end of the line");
						}
						//cout<<vstr[a].str<<"|";
						if(vstr[a].str=="("){
							pk++;
						}else if(vstr[a].str==")"){
							pk--;
						}
						if(pk){
							vt.push_back(vstr[a]);
						}else{
							if(vstr[a].str==","){
								vtt.push_back(vt);
								vt.clear();
							}else{
								vt.push_back(vstr[a]);
							}
						}
						vstr[a].str="";
						//cout<<"|"<<vstr[a].str<<"|";
					}
					vstr[a].str="";
					vtt.push_back(vt);
				}else{
					throw(error("SyntaxError : Expect a \'(\' after print but not found"));
				}
				for(vector<token> &onarg:vtt){
					for(token &onet:explain(onarg,pc)){
						//cout<<"{"<<onet.str<<"}";
						if(onet.str=="")continue;
						value va=atov(onet.str);
						switch(va.ty){
							case Z_INT:
								exit(va.data.ll);
								break;
							default:
								//cout<<int(va.ty);
								throw error("RuntimeError : Can\'t exit the value that\'s type is a unknown type");
								break;
						}
					}
				}
			}
			else{
				throw(error(string("SyntaxError : No such command \'")+vstr[a].str+"\'"));
			}
		}
	}
	for(int a=0;a<vstr.size();a++){
		if(vstr[a].str.empty())continue;
		if(vstr[a].wv==Z_ADD_MATH){
			
		}
	}
//	for(int a=vstr.size()-1;a>=0;a--){
//		if(vstr[a].wv==Z_GJZ){
//			if(vstr[a].str=="print"){
//				load_on_GJZ
//				for(auto &vta:vtt){
//					for(auto &a:vta){
//						cout<<a.str<<" ";
//					}
//					for(auto &a:explain(vta,pc)){
//						//cout<<"[\n"<<a.str<<"]\n";
//						value v=atov(a.str);
//						switch(v.ty){
//							case Z_INT:
//								cout<<v.data.ll;
//								break;
//							case Z_STR:
//								cout<<*v.data.strp;
//								break;
//						}
//					}
//				}
//			}else if(vstr[a].str=="in"){
//				for(auto &a2:vstr){
//					cout<<a2.str<<"?";
//				}
//				load_on_GJZ
//				for(auto &a2:vstr){
//					cout<<a2.str<<"|";
//				}
//				bool oned=0;
//				for(auto &vta:vtt){
//					for(auto &a2:explain(vta,pc)){
//						if(oned)throw error("Syntax error: Only one arg is expected at most in the in parameter section.");
//						oned=1;
//						string instr="114514";
//						//cout<<'.'<<vstr[a].str<<",";
//						vstr.insert(vstr.begin()+a,instr);
//						a--;
//						//cout<<'.'<<vstr[a].str<<",";
//					}
//					oned=1;
//				}
//			}
//		}
//	}
	return vstr;
}